{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import os"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "   employee_id first_name last_name     email  phone_number   job_id   salary  \\\n",
      "0          100     Steven      King     SKING  515.123.4567  AD_PRES  24000.0   \n",
      "1          101      N_ann   Kochhar  NKOCHHAR  515.123.4568    AD_VP  17000.0   \n",
      "2          102        Lex   De Haan   LDEHAAN  515.123.4569    AD_VP  17000.0   \n",
      "3          103  Alexander    Hunold   AHUNOLD  590.423.4567  IT_PROG   9000.0   \n",
      "4          104      Bruce     Ernst    BERNST  590.423.4568  IT_PROG   6000.0   \n",
      "\n",
      "   commission_pct  manager_id  department_id  \n",
      "0             NaN         NaN           90.0  \n",
      "1             NaN       100.0           90.0  \n",
      "2             NaN       100.0           90.0  \n",
      "3             NaN       102.0           60.0  \n",
      "4             NaN       103.0           60.0  \n"
     ]
    }
   ],
   "source": [
    "df = pd.read_csv(\"data/employees.csv\")# 加载员工数据\n",
    "print(df.head())"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 10,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "<class 'pandas.core.frame.DataFrame'>\n",
      "RangeIndex: 107 entries, 0 to 106\n",
      "Data columns (total 10 columns):\n",
      " #   Column          Non-Null Count  Dtype  \n",
      "---  ------          --------------  -----  \n",
      " 0   employee_id     107 non-null    int64  \n",
      " 1   first_name      107 non-null    object \n",
      " 2   last_name       107 non-null    object \n",
      " 3   email           107 non-null    object \n",
      " 4   phone_number    107 non-null    object \n",
      " 5   job_id          107 non-null    object \n",
      " 6   salary          107 non-null    float64\n",
      " 7   commission_pct  35 non-null     float64\n",
      " 8   manager_id      106 non-null    float64\n",
      " 9   department_id   106 non-null    float64\n",
      "dtypes: float64(4), int64(1), object(5)\n",
      "memory usage: 8.5+ KB\n",
      "----------------------------------------------------------------------------------------------------\n",
      "       employee_id        salary  commission_pct  manager_id  department_id\n",
      "count   107.000000    107.000000       35.000000  106.000000     106.000000\n",
      "mean    153.000000   6461.682243        0.222857  124.764151      63.207547\n",
      "std      31.032241   3909.365746        0.085184   20.315395      20.910110\n",
      "min     100.000000   2100.000000        0.100000  100.000000      10.000000\n",
      "25%     126.500000   3100.000000        0.150000  108.000000      50.000000\n",
      "50%     153.000000   6200.000000        0.200000  122.000000      50.000000\n",
      "75%     179.500000   8900.000000        0.300000  145.000000      80.000000\n",
      "max     206.000000  24000.000000        0.400000  205.000000     110.000000\n",
      "(107, 10)\n"
     ]
    }
   ],
   "source": [
    "df.info()# 查看数据信息\n",
    "print(\"----------\"*10)\n",
    "print(df.describe())# 查看统计信息\n",
    "print(df.shape)# 查看数据形状"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "    employee_id first_name last_name    email  phone_number    job_id  salary  \\\n",
      "32          132         TJ     Olson  TJOLSON  650.124.8234  ST_CLERK  2100.0   \n",
      "\n",
      "    commission_pct  manager_id  department_id  \n",
      "32             NaN       121.0           50.0  \n",
      "   employee_id first_name last_name  email  phone_number   job_id   salary  \\\n",
      "0          100     Steven      King  SKING  515.123.4567  AD_PRES  24000.0   \n",
      "\n",
      "   commission_pct  manager_id  department_id  \n",
      "0             NaN         NaN           90.0  \n"
     ]
    }
   ],
   "source": [
    "print(df.loc[df[\"salary\"] == df[\"salary\"].min()])# 找出最低薪资的员工\n",
    "print(df.loc[df[\"salary\"] == df[\"salary\"].max()])# 找出最高薪资的员工"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 15,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "     employee_id first_name  last_name     email        phone_number   job_id  \\\n",
      "0            100     Steven       King     SKING        515.123.4567  AD_PRES   \n",
      "1            101      N_ann    Kochhar  NKOCHHAR        515.123.4568    AD_VP   \n",
      "2            102        Lex    De Haan   LDEHAAN        515.123.4569    AD_VP   \n",
      "45           145       John    Russell   JRUSSEL  011.44.1344.429268   SA_MAN   \n",
      "46           146      Karen   Partners  KPARTNER  011.44.1344.467268   SA_MAN   \n",
      "101          201    Michael  Hartstein  MHARTSTE        515.123.5555   MK_MAN   \n",
      "8            108      Nancy  Greenberg  NGREENBE        515.124.4569   FI_MGR   \n",
      "47           147    Alberto  Errazuriz  AERRAZUR  011.44.1344.429278   SA_MAN   \n",
      "105          205    Shelley    Higgins  SHIGGINS        515.123.8080   AC_MGR   \n",
      "68           168       Lisa       Ozer     LOZER  011.44.1343.929268   SA_REP   \n",
      "\n",
      "      salary  commission_pct  manager_id  department_id  \n",
      "0    24000.0             NaN         NaN           90.0  \n",
      "1    17000.0             NaN       100.0           90.0  \n",
      "2    17000.0             NaN       100.0           90.0  \n",
      "45   14000.0            0.40       100.0           80.0  \n",
      "46   13500.0            0.30       100.0           80.0  \n",
      "101  13000.0             NaN       100.0           20.0  \n",
      "8    12000.0             NaN       101.0          100.0  \n",
      "47   12000.0            0.30       100.0           80.0  \n",
      "105  12000.0             NaN       101.0          110.0  \n",
      "68   11500.0            0.25       148.0           80.0  \n"
     ]
    }
   ],
   "source": [
    "print(df.nlargest(10, \"salary\"))# 薪资最高的10名员工"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 16,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "[ 90.  60. 100.  30.  50.  80.  nan  10.  20.  40.  70. 110.]\n",
      "department_id\n",
      "10.0      1\n",
      "20.0      2\n",
      "30.0      6\n",
      "40.0      1\n",
      "50.0     45\n",
      "60.0      5\n",
      "70.0      1\n",
      "80.0     34\n",
      "90.0      3\n",
      "100.0     6\n",
      "110.0     2\n",
      "Name: employee_count, dtype: int64\n"
     ]
    }
   ],
   "source": [
    "print(df[\"department_id\"].unique())# 所有部门id\n",
    "print(df.groupby(\"department_id\")[\"employee_id\"].count().rename(\"employee_count\"))# 查看每个部门的员工数"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 17,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/plain": [
       "<Axes: xlabel='department_id'>"
      ]
     },
     "execution_count": 17,
     "metadata": {},
     "output_type": "execute_result"
    },
    {
     "data": {
      "image/png": "iVBORw0KGgoAAAANSUhEUgAAAh8AAAHKCAYAAACjRinQAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMiwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy8pXeV/AAAACXBIWXMAAA9hAAAPYQGoP6dpAAAqYUlEQVR4nO3de3hU5YHH8d9ALkzIhZtMEgkQy0WQVZC4bECbKAZFhVDWCgUFquuCoCWlCwhsS2QlgFrElcpWHwW2isFWQH1akKAIYgwmgSBE5BokhQS8AOGalPDuHz7MOiYBAsk7c8L38zznj3PekzO/vM+R/Dxz5ozLGGMEAABgSSN/BwAAAFcXygcAALCK8gEAAKyifAAAAKsoHwAAwCrKBwAAsIryAQAArAryd4AfO3funA4ePKiIiAi5XC5/xwEAAJfAGKPjx48rNjZWjRpd+NpGwJWPgwcPKi4uzt8xAADAZSguLlabNm0uuE/AlY+IiAhJ34ePjIz0cxoAAHApysrKFBcX5/07fiEBVz7Ov9USGRlJ+QAAwGEu5ZYJbjgFAABWUT4AAIBVlA8AAGAV5QMAAFhF+QAAAFZRPgAAgFWUDwAAYBXlAwAAWEX5AAAAVlE+AACAVZQPAABgFeUDAABYRfkAAABWUT4AAIBVlA8AAGBVkL8DAPDV/sm/1tux982+t96ODQCXiisfAADAKsoHAACwivIBAACsonwAAACrKB8AAMAqygcAALCK8gEAAKyifAAAAKsoHwAAwCrKBwAAsIryAQAArKJ8AAAAqygfAADAKsoHAACwivIBAACsonwAAACrKB8AAMAqygcAALCK8gEAAKyifAAAAKsoHwAAwCrKBwAAsIryAQAArKJ8AAAAqygfAADAKsoHAACwivIBAACsonwAAACrKB8AAMAqygcAALCK8gEAAKyifAAAAKsoHwAAwCrKBwAAsOqKysesWbPkcrmUlpbm3WaMUXp6umJjY+V2u5WcnKzCwsIrzQkAABqIyy4fubm5evnll3XjjTf6bH/mmWc0d+5czZ8/X7m5uYqOjlZKSoqOHz9+xWEBAIDzXVb5OHHihIYPH65XXnlFzZs39243xmjevHmaNm2aBg8erG7dumnx4sU6deqUlixZUmehAQCAc11W+Rg3bpzuvfde3XnnnT7bi4qKVFpaqn79+nm3hYaGKikpSdnZ2dUeq7y8XGVlZT4LAABouIJq+wOZmZnatGmTcnNzq4yVlpZKkjwej892j8ejr776qtrjzZo1S0899VRtYwAAAIeq1ZWP4uJijR8/Xq+//rqaNGlS434ul8tn3RhTZdt5U6ZM0bFjx7xLcXFxbSIBAACHqdWVj/z8fB0+fFg9e/b0bqusrNT69es1f/587dixQ9L3V0BiYmK8+xw+fLjK1ZDzQkNDFRoaejnZAQCAA9Xqykffvn21detWFRQUeJeEhAQNHz5cBQUFuu666xQdHa2srCzvz1RUVGjdunXq3bt3nYcHAADOU6srHxEREerWrZvPtqZNm6ply5be7WlpacrIyFDHjh3VsWNHZWRkKCwsTMOGDau71AAAwLFqfcPpxUyaNEmnT5/W2LFjdeTIEfXq1UurV69WREREXb8UAABwIJcxxvg7xA+VlZUpKipKx44dU2RkpL/jANa1f/Kv9XbsfbPvrbdjA7i61ebvN9/tAgAArKJ8AAAAqygfAADAKsoHAACwivIBAACsonwAAACrKB8AAMAqygcAALCK8gEAAKyifAAAAKsoHwAAwCrKBwAAsIryAQAArKJ8AAAAqygfAADAKsoHAACwivIBAACsonwAAACrKB8AAMAqygcAALCK8gEAAKyifAAAAKsoHwAAwCrKBwAAsIryAQAArKJ8AAAAqygfAADAKsoHAACwivIBAACsonwAAACrKB8AAMAqygcAALCK8gEAAKyifAAAAKsoHwAAwCrKBwAAsIryAQAArKJ8AAAAqygfAADAKsoHAACwKsjfAQAAl6b9k3+tt2Pvm31vvR0b+DGufAAAAKsoHwAAwCrKBwAAsIryAQAArKJ8AAAAqygfAADAKsoHAACwivIBAACsonwAAACrKB8AAMAqygcAALCK8gEAAKyifAAAAKsoHwAAwCrKBwAAsIryAQAArKJ8AAAAqygfAADAKsoHAACwivIBAACsonwAAACrKB8AAMAqygcAALCK8gEAAKyifAAAAKsoHwAAwKpalY8FCxboxhtvVGRkpCIjI5WYmKiVK1d6x40xSk9PV2xsrNxut5KTk1VYWFjnoQEAgHPVqny0adNGs2fPVl5envLy8nTHHXcoNTXVWzCeeeYZzZ07V/Pnz1dubq6io6OVkpKi48eP10t4AADgPLUqHwMGDNA999yjTp06qVOnTpo5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zucrLy+Xx+PxGfN4PPr666/9EatG/fv314IFCyRJSUlJ+stf/uIz/tZbb6lDhw7+iHbJgoOD9cADD2jVqlXau3evHn30Ub3xxhvq3Lmzv6P5iI6O1hdffCFJ2rVrlyorK73rklRYWKjWrVv7K161Bg0apDFjxmjVqlVau3athg8frqSkJO8zJ3bs2BFQjymXpI0bN+q3v/1tlcfBS9/fsD516lRt3LjRD8lq1r17d/Xo0UPdu3evsvTo0cNv910Fzt1H9aBnz57atGmTBg0aVO24y+WSCaD7ba+//nrl5eVV+bTFiy++KGOMBg4c6KdkNWvfvr12797t/SPy6aefqm3btt7x4uJixcTE+CveBYWHh2vx4sXKzMxUSkqKKisr/R3pgvr27augoCCVlZVp586duuGGG7xj+/fvV6tWrfyYrqo5c+aoT58+SkpKUkJCgn7/+9/ro48+UpcuXbRjxw7l5ORo+fLl/o55ydq2bav09HRNnz5da9as8XccH8OGDdOIESOUmpqqDz74QJMnT9Z//Md/6Ntvv5XL5dLMmTN1//33+zumj6efflolJSUaMGCAKisrlZiYqNdff9077nK5NGvWLD8mrOr8A+hq+l6fQHwAXcuWLTVnzhz17du32vHCwkINGDDAcqoGXj4mTpyokydP1jjeoUOHgPrSop/97Gd688039dBDD1UZmz9/vs6dO6f/+Z//8UOymj322GM+f7S7devmM75y5cqA+7TLjw0dOlS33nqr8vPz1a5dO3/Hqdb06dN91sPCwnzW33vvvYD7dEZsbKw2b96s2bNn67333pMxRp999pmKi4vVp08fffLJJ0pISPB3zCratWt3wY94ulwupaSkWEx0cU899ZTcbrdycnI0evRoTZ48WTfeeKMmTZqkU6dOacCAAfqv//ovf8f0ER4erqVLl+rMmTM6e/aswsPDfcb79evnp2Q1O/9U1v/8z/9USkqKPB6PXC6XSktLlZWVpYyMDKWlpfk7po+ePXvq4MGDNf7bdvToUb/8T/hV/VFbAABqY86cOXrhhRe8X00vff+V9dHR0UpLS9OkSZP8nNDX8uXLdfLkST344IPVjh85ckTvvvuuRo4caTUX5QMAgFriAXRXpkHfcAoAQH2Ij49XYmKiEhMTvcWjuLhYDz/8sJ+T1Y6/MnPlAwCAOrBlyxbdfPPNAX/z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",
      "text/plain": [
       "<Figure size 640x480 with 1 Axes>"
      ]
     },
     "metadata": {},
     "output_type": "display_data"
    }
   ],
   "source": [
    "df.groupby(\"department_id\")[\"employee_id\"].count().rename(\"employee_count\").plot(kind=\"bar\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 20,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/plain": [
       "1    A\n",
       "2    B\n",
       "4    D\n",
       "5    E\n",
       "7    G\n",
       "8    H\n",
       "dtype: object"
      ]
     },
     "execution_count": 20,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "s1 = pd.Series([\"A\", \"B\"], index=[1, 2])\n",
    "s2 = pd.Series([\"D\", \"E\"], index=[4, 5])\n",
    "s3 = pd.Series([\"G\", \"H\"], index=[7, 8])\n",
    "pd.concat([s1, s2, s3])# 按行连接"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 21,
   "metadata": {
    "scrolled": true
   },
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>0</th>\n",
       "      <th>1</th>\n",
       "      <th>2</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>A</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>B</td>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>NaN</td>\n",
       "      <td>D</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>NaN</td>\n",
       "      <td>E</td>\n",
       "      <td>NaN</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>7</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>G</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>8</th>\n",
       "      <td>NaN</td>\n",
       "      <td>NaN</td>\n",
       "      <td>H</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "     0    1    2\n",
       "1    A  NaN  NaN\n",
       "2    B  NaN  NaN\n",
       "4  NaN    D  NaN\n",
       "5  NaN    E  NaN\n",
       "7  NaN  NaN    G\n",
       "8  NaN  NaN    H"
      ]
     },
     "execution_count": 21,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.concat([s1, s2, s3], axis=1)# 按列连接"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 27,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "   a  b\n",
      "1  1  4\n",
      "2  2  5\n",
      "     a    b     0\n",
      "1  1.0  4.0   NaN\n",
      "2  2.0  5.0   NaN\n",
      "1  NaN  NaN   7.0\n",
      "2  NaN  NaN  10.0\n",
      "****************************************************************************************************\n"
     ]
    },
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>a</th>\n",
       "      <th>b</th>\n",
       "      <th>a</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>4</td>\n",
       "      <td>7</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2</td>\n",
       "      <td>5</td>\n",
       "      <td>10</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   a  b   a\n",
       "1  1  4   7\n",
       "2  2  5  10"
      ]
     },
     "execution_count": 27,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df1 = pd.DataFrame(data={\"a\": [1, 2], \"b\": [4, 5]}, index=[1, 2])\n",
    "print(df1)\n",
    "s1 = pd.Series(data=[7, 10], index=[1, 2], name=\"a\")\n",
    "\n",
    "res=pd.concat([df1, s1])# 按行连接\n",
    "print(res)\n",
    "print('*'*100)\n",
    "pd.concat([df1, s1], axis=1)# 按列连接"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 32,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>a</th>\n",
       "      <th>b</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>4</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>7</td>\n",
       "      <td>10</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>8</td>\n",
       "      <td>11</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   a   b\n",
       "1  1   4\n",
       "2  2   5\n",
       "0  7  10\n",
       "1  8  11"
      ]
     },
     "execution_count": 32,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df1 = pd.DataFrame(data={\"a\": [1, 2], \"b\": [4, 5]}, index=[1, 2])\n",
    "df2 = pd.DataFrame(data={\"a\": [7, 8], \"b\": [10, 11]})\n",
    "\n",
    "pd.concat([df1, df2])# 按行连接\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 31,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>a</th>\n",
       "      <th>b</th>\n",
       "      <th>a</th>\n",
       "      <th>b</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>4</td>\n",
       "      <td>7</td>\n",
       "      <td>10</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2</td>\n",
       "      <td>5</td>\n",
       "      <td>8</td>\n",
       "      <td>11</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   a  b  a   b\n",
       "1  1  4  7  10\n",
       "2  2  5  8  11"
      ]
     },
     "execution_count": 31,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "pd.concat([df1, df2], axis=1)# 按列连接"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 33,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>a</th>\n",
       "      <th>b</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>1</td>\n",
       "      <td>4</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>2</td>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>7</td>\n",
       "      <td>10</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>8</td>\n",
       "      <td>11</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   a   b\n",
       "0  1   4\n",
       "1  2   5\n",
       "2  7  10\n",
       "3  8  11"
      ]
     },
     "execution_count": 33,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df1 = pd.DataFrame(data={\"a\": [1, 2], \"b\": [4, 5]}, index=[1, 2])\n",
    "df2 = pd.DataFrame(data={\"a\": [7, 8], \"b\": [10, 11]}, index=[1, 2])\n",
    "\n",
    "pd.concat([df1, df2], ignore_index=True)# 重置索引"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 34,
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>b</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>4</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>5</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>7</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>8</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "</div>"
      ],
      "text/plain": [
       "   b\n",
       "1  4\n",
       "2  5\n",
       "2  7\n",
       "3  8"
      ]
     },
     "execution_count": 34,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "df1 = pd.DataFrame(data={\"a\": [1, 2], \"b\": [4, 5]}, index=[1, 2])\n",
    "df2 = pd.DataFrame(data={\"b\": [7, 8], \"c\": [10, 11]}, index=[2, 3])\n",
    "\n",
    "\n",
    "pd.concat([df1, df2], join=\"inner\")"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 39,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  employee        group\n",
      "0      Bob   Accounting\n",
      "1     Jake  Engineering\n",
      "2     Lisa  Engineering\n",
      "3      Sue           HR\n",
      "  employee  hire_date\n",
      "0     Lisa       2004\n",
      "1      Bob       2008\n",
      "2     Jake       2012\n",
      "3      Sue       2014\n",
      "  employee        group  hire_date\n",
      "0      Bob   Accounting       2008\n",
      "1     Jake  Engineering       2012\n",
      "2     Lisa  Engineering       2004\n",
      "3      Sue           HR       2014\n"
     ]
    }
   ],
   "source": [
    "#一对一链接\n",
    "df1 = pd.DataFrame({\"employee\": [\"Bob\", \"Jake\", \"Lisa\", \"Sue\"], \"group\": [\"Accounting\", \"Engineering\", \"Engineering\", \"HR\"]})\n",
    "df2 = pd.DataFrame({\"employee\": [\"Lisa\", \"Bob\", \"Jake\", \"Sue\"], \"hire_date\": [2004, 2008, 2012, 2014]})\n",
    "\n",
    "print(df1)\n",
    "print(df2)\n",
    "\n",
    "df3 = pd.merge(df1, df2)\n",
    "print(df3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 41,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  employee        group supervisor\n",
      "0      Bob   Accounting      Carly\n",
      "1     Jake  Engineering      Guido\n",
      "2     Lisa  Engineering      Guido\n",
      "3      Sue           HR      Steve\n"
     ]
    }
   ],
   "source": [
    "#一对多链接\n",
    "df1 = pd.DataFrame({\"employee\": [\"Bob\", \"Jake\", \"Lisa\", \"Sue\"], \"group\": [\"Accounting\", \"Engineering\", \"Engineering\", \"HR\"]})\n",
    "df2 = pd.DataFrame({\"group\": [\"Accounting\", \"Engineering\", \"HR\"], \"supervisor\": [\"Carly\", \"Guido\", \"Steve\"]})\n",
    "# print(df1)\n",
    "#   employee        group\n",
    "# 0      Bob   Accounting\n",
    "# 1     Jake  Engineering\n",
    "# 2     Lisa  Engineering\n",
    "# 3      Sue           HR\n",
    "# print(df2)\n",
    "\n",
    "df3 = pd.merge(df1, df2)\n",
    "print(df3)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 42,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "  employee        group        skills\n",
      "0      Bob   Accounting          math\n",
      "1      Bob   Accounting  spreadsheets\n",
      "2     Jake  Engineering        coding\n",
      "3     Jake  Engineering         linux\n",
      "4     Lisa  Engineering        coding\n",
      "5     Lisa  Engineering         linux\n",
      "6      Sue           HR  spreadsheets\n",
      "7      Sue           HR  organization\n"
     ]
    }
   ],
   "source": [
    "df1 = pd.DataFrame({\"employee\": [\"Bob\", \"Jake\", \"Lisa\", \"Sue\"], \"group\": [\"Accounting\", \"Engineering\", \"Engineering\", \"HR\"]})\n",
    "df2 = pd.DataFrame({\"group\": [\"Accounting\", \"Accounting\", \"Engineering\", \"Engineering\", \"HR\", \"HR\"], \"skills\": [\"math\", \"spreadsheets\", \"coding\", \"linux\", \"spreadsheets\", \"organization\"],})\n",
    "\n",
    "df3 = pd.merge(df1, df2)\n",
    "print(df3)"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.11.5"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 1
}
